#!/usr/bin/env python
# -*- coding: utf-8 -*-

# Plugin demo escrito por Diego Hahn - 2010

import gtk

import struct
import array

import pluginmanager
import dialogs

flag = "HEAVEN"

@pluginmanager.register('HEAVEN-SCAN')
def heaven_scan(*args, **kwargs):
	fmap = kwargs['infile']

	fmap.seek(0xa0, 0)
	if fmap.read(12) == 'YGGDRA UNION':
		offsets =  [1804384L, 1804424L, 1804464L, 1804504L, 1804544L, 1804584L, 1804624L, 1804664L,
					1804704L, 1804744L, 1804784L, 1804824L, 1804864L, 1804904L, 1804944L, 1804984L,
					1805024L, 1805064L, 1805104L, 1805144L, 1805184L, 1805224L, 1805264L, 1805304L,
					1805344L, 1805384L, 1805424L, 1805464L, 1805504L, 1805544L, 1805584L, 1805624L,
					1805664L, 1805704L, 1805744L, 1805784L, 1805824L, 1805864L, 1805904L, 1805944L,
					1805984L, 1806024L, 1806064L, 1806104L, 1806144L, 1806184L, 1806224L, 1806264L,
					1806304L, 1806344L, 1806384L, 1806424L, 1808184L, 1808204L, 1808224L, 1808244L,
					1808264L]
	else:
		dialogs.Error(None, 'yggdra_decoder.py\n\nA ROM informada não é suportada por este plugin.')
		return []
#
	results = []
	for index in range(len(offsets)):

		fmap.seek(offsets[index], 0)
		results.append(((struct.unpack('<L', fmap.read(4))[0] - 0x08000000), flag))

		while gtk.events_pending():
			gtk.main_iteration()

	return results

@pluginmanager.register('HEAVEN-UNCOMPRESS')
def heaven_uncompress(*args, **kwargs):
	fd = kwargs['infile']
	headerAddress = kwargs['address']

	fd.seek(headerAddress, 0)

	output = array.array('c')

	currentIter = 0
	totalIter = struct.unpack('<H', fd.read(2))[0]

	headerAddress += 2
	dataAddress = headerAddress + (totalIter << 1)

	while currentIter <= totalIter:
		fd.seek(headerAddress, 0)
		headerAddress += 2

		headerPar = struct.unpack('<H', fd.read(2))[0]
		if headerPar == 0:
			break

		flag = (((headerPar & 0x8000) << 0x10) & 0xFFFFFFFF) >> 0x10
		# flag = 0000h ou 8000h
		if flag == 0:
			# Lê dados da ROM
			fd.seek(dataAddress, 0)
			wordCount = ((headerPar << 0x11) & 0xFFFFFFFF) >> 0x11

			for x in range(wordCount << 1):
				output.append(fd.read(1))
			dataAddress += (wordCount << 1)

		else:
			# Lê dados da RAM
			wordCount = (((headerPar >> 0x0a) & 0x1f) + 2)
			ramDistance = (headerPar & 0x3ff) << 1

			for x in range(wordCount << 1):
				output.append(output[len(output) - ramDistance])

	return output
